package edu.hawaii.duedates;

import java.util.ArrayList;
import java.util.List;

import com.meterware.httpunit.WebConversation;

/**
 * General Library class for the underlining basis of what is required
 * for dealing with connections, logins and data retrieval.
 * @author Anthony Du
 *
 */
public abstract class Library implements Comparable<Library> {
  private String libname;
  private final List<LibraryUser> libUsers = new ArrayList<LibraryUser>();
  private final List<Book> books = new ArrayList<Book>();

  /**
   * Default constructor.
   */
  protected Library() {
    libname = "Onestop Books";
  }

  /**
   * Library class constructor for initializing the library name.
   * @param name String name of library.
   */
  protected Library(String name) {
    libname = name;
  }

  /**
   * Sets the name of the library.
   * @param name String name of library
   */
  protected void setLibName(String name) {
    libname = name;
  }

  /**
   * Gets the library's name.
   * @return String containing the library's name.
   */
  public String getLibName() {
    return libname;
  }

  /**
   * Add a library user to a list of users.
   * @param u LibraryUser object.
   * @return boolean of true/false.
   */
  protected boolean addLibUser(LibraryUser u) {
    return libUsers.add(u);
  }

  /**
   * Gets a list of all library users.
   * @return List of all library users.
   */
  protected List<LibraryUser> getLibUsers() {
    return libUsers;
  }

  /**
   * Add a library book to a list of books.
   * @param b Book object.
   * @return boolean of true/false.
   */
  public boolean addBook(Book b) {
    return books.add(b);
  }

  /**
   * Gets a list of all library books.
   * @return List of all library books.
   */
  protected List<Book> getBooks() {
    return books;
  }

  /**
   * CompareTo method for library class.
   * @param lib Library object.
   * @return int of 0, -1, or 1.
   */
  public int compareTo(Library lib) {
    return this.libname.compareTo(lib.getLibName());
  }
  
  /**
   * Equals is used to check equality of a give book object.
   * @param obj The object being passed for equality check.
   * @return boolean value of true/false.
   */
  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Library) {
      Library b = (Library) obj;
      return b.getLibName().equals (this.libname);
    }
    return false;
  }
  
  /**
   * HashCode for generating a unique hashcode coupled by the book's attributes.
   * @return int a unique book hashcode.
   */
  @Override 
  public int hashCode() {
    return this.libname.hashCode();
  }

  /**
   * Authenticate users who attempt to log into library system.
   * @param user LibraryUser object.
   * @return WebConversation object.
   * @throws Exception 
   * @exception Exception when error occurs.
   */
  protected abstract WebConversation logIntoLibrary(LibraryUser user) throws Exception;

  /**
   * Retrieve data from the library system after successful authentication.
   * @param user LibraryUser object. 
   * @return String containing info regarding users.
   * @exception Exception when error occurs.
   */
  protected abstract String getLibInfo(LibraryUser user) throws Exception;
}
